//注入后台服务操作对象,全局使用
import socketStore from '@/cache/socketStore.js'

export default {
	install(Vue, options) {
		var vm = new Vue(options)
		// 在Vue的原型上添加实例方法，以全局调用
		Vue.prototype.$wedoSocketServer = {
			bean: undefined,
			url: undefined,
			usercode: undefined,
			heartTime: 0, //上次心跳时间
			messageListener: {
				//监听列表，想要知道消息的就add进来,key是唯一标志,参数是收到的事件对象
			},
			checkConnectTimer: undefined,
			dealAnnounceMsg(message) {
				try {
					var msg = message.Msg
					var params = message.Params
					var data = JSON.parse(message.Data)
					var title = data.Title
					var content = data.Content
					//处理推送类消息
					switch (message.Cmd) {
						case 0:
							//要添加到记录中的事件对象
							var eventItem = {}
							//所属单位
							eventItem.unitName = params.unitname
							//事件时间
							eventItem.eventTime = params.eventtime
							//事件类型名称
							eventItem.typeName = data.Title
							//事件内容
							eventItem.content = data.Content
							//事件类型对象
							var eventTag = JSON.parse(data.Tag)
							eventItem.typeBean = eventTag
							//事件等级
							var level = eventTag.EventLevel
							socketStore.commit("addRealTimeEvent", eventItem)
							if (level == undefined || level <= 0) {
								//消息类，右下角弹窗就好了
								return
							}
							vm.$dialogMethod.openEventAlarm(socketStore.getters.getRealTimeEventList)
							break;
						case 1:
							//公告
							socketStore.commit("addPushMessage", content)
							vm.$dialogMethod.showMessage(content)
							break;
						case 2:
							//工单
							log("未处理工单消息" + JSON.stringify(message))
							break;
						default:
							log("未知的消息内容" + JSON.stringify(message))
							break;
					}

				} catch (e) {
					err(e.stack)
				}
			},
			connect(url, usercode) {
				this.disConnect()
				//保存连接的url,方便自动重连
				var bean
				try {
					bean = new WebSocket(url)
				} catch (e) {
					//创建失败了,返回并且打印失败信息
					err(e.stack)
					return
				}
				this.url = url
				this.usercode = usercode
				bean.addEventListener("open", events => {
					log("socket服务连接成功,开始登陆!url:" + this.url + "  usercode:" + this.usercode)
					bean.send(this.getMessage(0, 1, usercode))
					this.heartTime = new Date().getTime()
					this.checkConnectTimer = setInterval(() => {
						if (new Date().getTime() - this.heartTime > 20 * 1000) {
							//20秒无心跳或者通信则重连
							this.connect(this.url, this.usercode)
						} else if (new Date().getTime() - this.heartTime > 5 * 1000) {
							//超过5秒无通信则发送心跳
							try {
								this.bean.send(this.getMessage(0, 0, ""))
							} catch (e) {
								//通道可能断开了
								this.connect(this.url, this.usercode)
							}
						}
					}, 5000)
				})
				bean.addEventListener("close", events => {
					log("socket服务断开!")
				})
				bean.addEventListener("message", events => {
					var data = events.data
					try {
						data = JSON.parse(events.data)
					} catch (e) {
						//消息解析异常
						err("异常消息类型" + events.data)
						return
					}
					//刷新最后通讯时间
					this.heartTime = new Date().getTime()
					if (data.Func == 0 && data.Cmd == 0) {
						//心跳,忽略
						return
					}
					if (data.Func == 0 && data.Cmd == 1) {
						//用户登录的反馈
						log("用户登录 " + (data.Success ? "成功" : "失败"))
						return
					}
					if (data.Func == 1) {
						this.dealAnnounceMsg(data)
					} else {
						log("未知的消息:" + events.data)
					}
					var keys = Object.keys(this.messageListener)
					for (var i = 0, len = keys.length; i < len; i++) {
						try {
							this.messageListener[keys[i]](events)
						} catch (e) {
							err(e.stack)
						}
					}
				})
				bean.addEventListener("error", events => {
					err(events)
				})
				this.bean = bean
			},
			disConnect() {
				if (this.bean != undefined) {
					//关闭连接
					this.bean.close()
					this.bean = undefined
				}
				if (this.checkConnectTimer != undefined) {
					//关闭重连定时器
					clearInterval(this.checkConnectTimer)
					this.checkConnectTimer = undefined
				}
				//移除保存的上次连接地址
				this.url = undefined
			},
			addMessageListener(tag, method) {
				this.messageListener[tag] = method
			},
			removeMessageListener(tag) {
				delete this.messageListener[tag]
			},
			getMessage(Func, Cmd, Data) {
				return JSON.stringify({
					Func,
					Cmd,
					Data,
					Code: new Date().getTime()
				})
			},
		}
	}
}
